package com.kgc.interceptor;

import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.kgc.annotation.CheckPermission;
import com.kgc.entity.User;
import com.kgc.service.UserService;
import com.kgc.util.JwtUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Component
public class UserCheckInterceptor implements HandlerInterceptor {

    public static final Logger log = LoggerFactory.getLogger(UserCheckInterceptor.class);

    private final StringRedisTemplate stringRedisTemplate;
    private final UserService userService;

    @Autowired
    public UserCheckInterceptor(StringRedisTemplate redisTemplate, UserService userService) {
        this.stringRedisTemplate = redisTemplate;
        this.userService = userService;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        log.debug("请求地址：" + request.getRequestURI());
        //请求的静态资源
        boolean isHandlerMethod = handler instanceof HandlerMethod;
        if (!isHandlerMethod) {
            return true;
        }
        //是否有权限注解
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        CheckPermission checkPermission = handlerMethod.getMethodAnnotation(CheckPermission.class);
        if (checkPermission == null) {
            return true;
        }
        String token = request.getHeader("Authorization");
        log.debug("token:" + token);
        //验证是否登录

        if (token == null || token.equals("")) {
            // 没有登录
            throw new RuntimeException("未登录");
        }
        log.debug("前端发送的token" + token);
        //验证token
        Long userID = null;
        try {
            userID = JwtUtil.getUserID(token);
            System.out.println("userId的值：" + userID);
            System.out.println("userId的值toString：" + userID.toString());
        } catch (SignatureVerificationException e) {
            throw new RuntimeException("验签错误");
        } catch (TokenExpiredException e) {
            throw new RuntimeException("登录超时");
        }
        String serverToken = stringRedisTemplate.opsForValue().get(userID.toString());
        log.debug("redis获取出来的数据" + serverToken);
        if (serverToken == null || !token.equals(serverToken)) {
            throw new RuntimeException("验签错误");
        }
        //toke延期
        Date exp = JwtUtil.getExpires(token);
        if (exp.getTime() - System.currentTimeMillis() <= 5 * 60 * 1000) {
            //进行token置换
            String newToken = JwtUtil.createToken(userID);
            stringRedisTemplate.opsForValue().set(userID.toString(), newToken, 30, TimeUnit.MINUTES);
            response.setHeader("Access-Control-Expose-Headers", "x-token");
            response.setHeader("x-token", newToken);
        }

        String[] roles = checkPermission.value();
        log.debug("角色权限：" + Arrays.toString(roles));
        if (checkRole(userID, roles)) {
            return true;
        } else {
            throw new RuntimeException("权限不足");
        }
    }

    public boolean checkRole(long userID, String[] roles) {
        User user = userService.selectUserById((int) userID);
        for (String role : roles) {
            if (role.equals(String.valueOf(user.getType()))) {
                return true;
            }
        }
        return false;
    }

}
